package com.icez.circle_image_view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewOutlineProvider
import android.widget.ImageView
import kotlin.math.min

/**
 * 圆形图片
 * @sample 
 * @author Icez
 */
@SuppressLint("AppCompatCustomView")
class CircleImageView @JvmOverloads constructor(
    val mContext: Context, val attrs: AttributeSet? = null
) : ImageView(mContext, attrs) {

    //圆形图片区域
    var mDrawableRect: RectF? = null

    //圆形图片边框区域
    var mBorderRect: RectF? = null

    //图片圆形背景画笔
    var mCircleBackgroundPaint: Paint? = null

    //圆形图片背景颜色
    var mCircleBackgroundColor:Int = Color.WHITE

    //位图画笔
    var mBitmapPaint: Paint? = null

    //位图画布
    var mBitmapCanvas: Canvas? = null

    //当前图片的位图
    var mBitmap: Bitmap? = null

    //圆形图片区域的半径
    var mDrawableRadius: Float = 0f

    //图片边框画笔
    var mBorderPaint: Paint? = null

    //圆形图片边框半径
    var mBorderRadius: Float = 0f

    //矩阵
    var mShaderMatrix: Matrix? = null

    //圆形边框的宽度
    var mBorderWidth: Float = 0f

    //圆形边框的颜色
    var mBorderColor:Int = Color.WHITE

    init {

        val typedArray = context.obtainStyledAttributes(attrs,R.styleable.CircleImageView)
        mBorderWidth = typedArray.getDimension(R.styleable.CircleImageView_border_width,0f)
        mBorderColor = typedArray.getColor(R.styleable.CircleImageView_border_color,Color.WHITE)
        mCircleBackgroundColor = typedArray.getColor(R.styleable.CircleImageView_background_color,Color.WHITE)
        typedArray.recycle()

        //初始化矩阵
        mShaderMatrix = Matrix()

        // 初始化图片区域
        mDrawableRect = RectF()
        // 初始化图片边框区域
        mBorderRect = RectF()

        //图片画笔
        // 初始化画笔
        mBitmapPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        //设置图片防抖动
        mBitmapPaint?.isDither = true
        //设置画笔颜色
        mBitmapPaint?.setColor(Color.WHITE)

        // 初始化边框画笔并抗锯齿
        mBorderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        //设置画笔颜色
        mBorderPaint?.setColor(mBorderColor)
        //设置空心
        mBorderPaint?.style = Paint.Style.STROKE
        //设置画笔宽度
        mBorderPaint?.strokeWidth = mBorderWidth

        //圆背景画笔
        // 初始化
        mCircleBackgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        // 设置填充
        mCircleBackgroundPaint?.style = Paint.Style.FILL
        // 设置颜色
        mCircleBackgroundPaint?.setColor(mCircleBackgroundColor)

    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        //计算当前控件的宽度
        val width = MeasureSpec.getSize(widthMeasureSpec)
        //计算当前控件的高度
        val height = MeasureSpec.getSize(heightMeasureSpec)
        //得到最小值
        val minValue = min(width, height)
        //重新设置当前控件的大小为正方形
        setMeasuredDimension(minValue, minValue)
    }

    override fun onDraw(canvas: Canvas?) {
        //获取当前图片的位图
        mBitmap = drawable?.let { drawableToBitmap(it) }
        // 判断当前是否有设置图片，并且是否可以修改
        if (mBitmap != null && mBitmap?.isMutable == true) {
            //初始化当前图片的画布
            mBitmapCanvas = Canvas(mBitmap!!)
            // 绘制圆背景
            mCircleBackgroundPaint?.let {
                canvas?.drawCircle(
                    mDrawableRect?.centerX() ?: 0f,
                    mDrawableRect?.centerY() ?: 0f,
                    mDrawableRadius,
                    it
                )
            }

            //设置图片的区域
            drawable.setBounds(0, 0, mBitmapCanvas?.width ?: 0, mBitmapCanvas?.height ?: 0)
            //绘制图片的区域
            mBitmapCanvas?.let { drawable.draw(it) }

            val bitmapShader =
                mBitmap?.let { BitmapShader(it, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) }
            val scale: Float
            var dx = 0f
            var dy = 0f
            mShaderMatrix?.set(null)
            val bitmapHeight = mBitmap?.height ?: 0
            val bitmapWidth = mBitmap?.width ?: 0
            if (bitmapWidth * (mDrawableRect?.height() ?: 0f) > (mDrawableRect?.width()
                    ?: 0f) * bitmapHeight
            ) {
                scale = (mDrawableRect?.height() ?: 0f) / bitmapHeight
                dx = ((mDrawableRect?.width() ?: 0f) - bitmapWidth * scale) * 0.5f
            } else {
                scale = (mDrawableRect?.width() ?: 0f) / bitmapWidth
                dy = ((mDrawableRect?.height() ?: 0f) - bitmapHeight * scale) * 0.5f
            }
            mShaderMatrix?.setScale(scale, scale)
            mShaderMatrix?.postTranslate(
                (dx + 0.5f).toInt() + (mDrawableRect?.left ?: 0f),
                (dy + 0.5f).toInt() + (mDrawableRect?.top ?: 0f)
            )

            bitmapShader?.setLocalMatrix(mShaderMatrix)
            mBitmapPaint?.shader = bitmapShader

            mBitmapPaint?.let {
                canvas?.drawCircle(
                    mDrawableRect?.centerX() ?: 0f,
                    mDrawableRect?.centerY() ?: 0f,
                    mDrawableRadius,
                    it
                )
            }

            if (mBorderRadius > 0) {
                mBorderPaint?.let {
                    canvas?.drawCircle(
                        mBorderRect?.centerX() ?: 0f, mBorderRect?.centerY() ?: 0f, mBorderRadius,
                        it
                    )
                }
            }
        } else {
            super.onDraw(canvas)
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //获取最小值
        val slideLength = min(width, height)
        //获取圆形的左边坐标
        val left = (width - slideLength) / 2f
        //获取圆形的上边坐标
        val top = (height - slideLength) / 2f
        //设置圆形边框的区域
        mBorderRect?.set(left, top, left + slideLength, top + slideLength)
        //设置圆形图片的区域
        mBorderRect?.let { mDrawableRect?.set(it) }
        //获取圆形边框的半径
        mBorderRadius =
            min(
                ((mDrawableRect?.height() ?: 0f) - mBorderWidth) / 2f,
                ((mDrawableRect?.width() ?: 0f) - mBorderWidth) / 2f
            )
        //获取圆形图片的半径
        mDrawableRadius =
            min((mDrawableRect?.height() ?: 0f) / 2f, (mDrawableRect?.width() ?: 0f) / 2f)
    }


    /**
     * Drawable 转换 Bitmap
     *
     * @param drawable Drawable对象
     * @return
     */
    public fun drawableToBitmap(
        drawable: Drawable
    ): Bitmap? {

        try {
            var bitmap: Bitmap? = null
            bitmap = Bitmap.createBitmap(
                drawable.intrinsicWidth,
                drawable.intrinsicHeight,
                Bitmap.Config.ARGB_8888
            )
            val canvas = Canvas(bitmap)
            drawable.setBounds(0, 0, canvas.width, canvas.height)
            drawable.draw(canvas)
            return bitmap
        } catch (ex: Exception) {
            return null
        }
    }
}